package org.streets.eis.component.organtree;

import java.util.Enumeration;
import java.util.List;

import javax.swing.tree.DefaultTreeModel;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.util.string.Strings;
import org.streets.database.Limits;
import org.streets.database.SQLConnection;
import org.streets.eis.EisWebSession;
import org.streets.eis.component.WebResources;
import org.streets.eis.component.tree.Node;
import org.streets.eis.component.tree.TreePanel;
import org.streets.eis.entity.Organization;
import org.streets.eis.entity.User;
import org.streets.eis.ext.rbac.services.RBACAuthorizer;
import org.streets.eis.types.UnitType;

public class OrganTree extends TreePanel<Organization>{
	
	private static final long serialVersionUID = 1L;
	
	public static final Organization DUMMY = new Organization();

	
	static{
		DUMMY.setId("");
	}
	
	@Inject
	protected SQLConnection connection;
	
	@Inject
	protected RBACAuthorizer authorizer;
		
	private String historyKey = "";
	
	protected String[] rootNodeIds;

	public OrganTree(String id){
		this(id,false);
	}
	
	public OrganTree(String id, boolean showCheckBox,String... rootNodeId){
		super(id,(DefaultTreeModel)null,showCheckBox);		
		rootNodeIds = rootNodeId;
		setPreSelectNode(true);

		Node<Organization> rootNode = new Node<Organization>(DUMMY){
			private static final long serialVersionUID = 1L;

			@Override
			protected void load(Node<Organization> node) {
				OrganTree.this.loadChildNode(node);				
			}	
		};
		
		DefaultTreeModel model = new DefaultTreeModel(rootNode);
		getTree().setDefaultModelObject(model);		
		getTree().setRootLess(true); 
		
	}
	
	public String getHistoryKey() {
		return historyKey;
	}

	public OrganTree setHistoryKey(String historyKey) {
		this.historyKey = historyKey;
		return this;
	}
	
	@SuppressWarnings("unchecked")
	public String getNodeIds(Node<Organization> node) {
		StringBuffer sb = new StringBuffer();
		Node<Organization> tmp = node;
		while (tmp != null) {
			sb.insert(0, tmp.getObject().getId());
			sb.insert(0, ",");
			tmp = (Node<Organization>) tmp.getParent();
		}
		return sb.substring(1).toString();
	}	
	
	@Override
	protected String getDefaultExpandedNodeIdSequence(){
		User user = EisWebSession.get().getUser(); //获取当前用户			
		return NodeHistoryManager.getSelectedNodeIds(connection, user.getUid(), historyKey);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected Node<Organization> getDefaultExpandedNode(){
		String nodeIds = getDefaultExpandedNodeIdSequence();
		
		if (!Strings.isEmpty(nodeIds)){			
			Node<Organization> rootNode = (Node<Organization>) getTree().getModelObject().getRoot();			
			if (rootNode!=null) {			
				int idx = nodeIds.indexOf(rootNode.getObject().getId()); 
				if (idx>=0){
					nodeIds = nodeIds.substring(idx+rootNode.getObject().getId().length());
					if (!Strings.isEmpty(nodeIds)){
						String[] nodeIdArray = nodeIds.substring(1).split(",");
				
						Node<Organization> node = rootNode;
						for (int i=0;i<nodeIdArray.length;i++){
							node.loadChildren();				
							String nodeId = nodeIdArray[i];
						
							Node<Organization> childNode = null;
							for (Enumeration<?> nodeEnum = node.children();nodeEnum.hasMoreElements();){
								Node<Organization> tmpNode = (Node<Organization>)nodeEnum.nextElement();
								if (nodeId.equals(tmpNode.getObject().getId())){
									childNode = tmpNode;
									break;
								}
							}
						
							if (childNode!=null) {
								node = childNode;
							} else {
								break;
							}
						}
					
						return node;
					} else {
						if (rootNode!=null) {
							return rootNode;
						}
					}
				}
			}
		}
		return super.getDefaultExpandedNode();
	}
	
	protected String generateSqlOR(String fieldName,String[] array){
		StringBuffer sb = new StringBuffer("(1=0 ");
		for (String key : array){
			sb.append(" OR ").append(fieldName).append("='").append(key).append("'");
		}
		sb.append(")");
		return sb.toString();
	}
	
	@Override
	protected void loadChildNode(Node<Organization> node){
		
		User user = EisWebSession.get().getUser(); //获取当前用户
		
		String parentId = node.getObject().getId();
				
		String organSql  = "";
		
		String userOrganSql = authorizer.generateUserOrganPermitSql(user);
		
		if (Strings.isEmpty(parentId)){
			boolean flag = rootNodeIds!=null && rootNodeIds.length>0;
			if (flag){ 
				organSql = String.format("SELECT * FROM EIS_ORGAN WHERE %s AND ID IN (%s)  ORDER BY SHOW_INDEX",
					generateSqlOR("ID",rootNodeIds),userOrganSql);
				flag = connection.count(organSql) > 0;
			}
			if (!flag) {
				organSql = String.format("SELECT * FROM EIS_ORGAN WHERE ID IN (%s) AND nvl(PARENT_ID,'#') NOT IN (%s)  ORDER BY SHOW_INDEX",
					userOrganSql,userOrganSql);	
			}
		} else {
			organSql = String.format("SELECT * from EIS_ORGAN WHERE PARENT_ID='%s' AND ID IN (%s) ORDER BY SHOW_INDEX",
					parentId,userOrganSql);
		}
		
		List<Organization> children = connection.query(organSql,Organization.class,Limits.none());
		for (Organization child : children){
			node.add(new Node<Organization>(child));
		}		
	}
	
	@Override
	protected void afterNodeLabelClicked(Node<Organization> node, BaseTree tree, AjaxRequestTarget target){
		if (!Strings.isEmpty(historyKey)){
			User user = EisWebSession.get().getUser(); //获取当前用户
			NodeHistoryManager.setSelectedNodeIds(connection, user.getUid(), historyKey, getNodeIds(node));
		}
	}

	@Override
	protected ResourceReference getNodeIcon(Node<Organization> node){
		Organization organ = node.getObject();
		String attr = organ.getAttr();
		if (Strings.isEmpty(attr)){
			return WebResources.Streets.Organ.DEPT_ICON;
		}
		
		if (attr.equals(String.valueOf(UnitType.GROUP.value()))){
			return WebResources.Streets.Organ.ENT_ICON;
		} else if (attr.equals(String.valueOf(UnitType.COMPANY.value()))){
			return WebResources.Streets.Organ.COMP_ICON;
		} else{
			return WebResources.Streets.Organ.DEPT_ICON;
		}
	}
}
